

<!DOCTYPE html>
<html lang="zh-CN" data-default-color-scheme=dark>



<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/my-blog/img/fluid.png">
  <link rel="icon" href="/my-blog/img/fluid.png">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="author" content="木舟">
  <meta name="keywords" content="python Vue Test 测试开发 自动化测试">
  
    <meta name="description" content="前言ORM实际上是django对数据库的各种操作进行封装后的api, 通过调用对应的api, 就能够生成对应的sql. 我们在 Django起步 中学习到了简单的ORM操作, 但是我们知道, sql的使用十分复杂. 所以即使进ORM进行了一定的封装, 变得更加简洁易用, 但面对一些复杂的sql, 仍然需要学习其他的api. 基础查询all查询所有对象，返回queryset对象。查询集，也称查询结果">
<meta property="og:type" content="article">
<meta property="og:title" content="Django-ORM操作进阶">
<meta property="og:url" content="https://walker_kwu.gitee.io/my-blog/2022/12/12/notes/django/ormAction/">
<meta property="og:site_name" content="My Blog">
<meta property="og:description" content="前言ORM实际上是django对数据库的各种操作进行封装后的api, 通过调用对应的api, 就能够生成对应的sql. 我们在 Django起步 中学习到了简单的ORM操作, 但是我们知道, sql的使用十分复杂. 所以即使进ORM进行了一定的封装, 变得更加简洁易用, 但面对一些复杂的sql, 仍然需要学习其他的api. 基础查询all查询所有对象，返回queryset对象。查询集，也称查询结果">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2022-12-12T07:08:12.000Z">
<meta property="article:modified_time" content="2023-05-23T10:37:53.250Z">
<meta property="article:author" content="木舟">
<meta property="article:tag" content="测试开发">
<meta property="article:tag" content="测试平台">
<meta property="article:tag" content="后端框架">
<meta name="twitter:card" content="summary_large_image">
  
  
    <meta name="referrer" content="no-referrer-when-downgrade">
  
  
  <title>Django-ORM操作进阶 - My Blog</title>

  <link  rel="stylesheet" href="https://lib.baomitu.com/twitter-bootstrap/4.6.1/css/bootstrap.min.css" />



  <link  rel="stylesheet" href="https://lib.baomitu.com/github-markdown-css/4.0.0/github-markdown.min.css" />

  <link  rel="stylesheet" href="https://lib.baomitu.com/hint.css/2.7.0/hint.min.css" />

  <link  rel="stylesheet" href="https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.css" />



<!-- 主题依赖的图标库，不要自行修改 -->
<!-- Do not modify the link that theme dependent icons -->

<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_hj8rtnfg7um.css">



<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_lbnruvf0jn.css">


<link  rel="stylesheet" href="/my-blog/css/main.css" />


  <link id="highlight-css" rel="stylesheet" href="/my-blog/css/highlight.css" />
  
    <link id="highlight-css-dark" rel="stylesheet" href="/my-blog/css/highlight-dark.css" />
  




  <script id="fluid-configs">
    var Fluid = window.Fluid || {};
    Fluid.ctx = Object.assign({}, Fluid.ctx)
    var CONFIG = {"hostname":"walker_kwu.gitee.io","root":"/my-blog/","version":"1.9.2","typing":{"enable":true,"typeSpeed":70,"cursorChar":"_","loop":false,"scope":[]},"anchorjs":{"enable":true,"element":"h1,h2,h3,h4,h5,h6","placement":"left","visible":"hover","icon":""},"progressbar":{"enable":true,"height_px":3,"color":"#29d","options":{"showSpinner":false,"trickleSpeed":100}},"code_language":{"enable":true,"default":"TEXT"},"copy_btn":true,"image_caption":{"enable":true},"image_zoom":{"enable":true,"img_url_replace":["",""]},"toc":{"enable":true,"placement":"left","headingSelector":"h1,h2,h3,h4,h5,h6","collapseDepth":0},"lazyload":{"enable":true,"loading_img":"/img/loading.gif","onlypost":false,"offset_factor":2},"web_analytics":{"enable":false,"follow_dnt":true,"baidu":null,"google":null,"gtag":null,"tencent":{"sid":null,"cid":null},"woyaola":null,"cnzz":null,"leancloud":{"app_id":null,"app_key":null,"server_url":null,"path":"window.location.pathname","ignore_local":false}},"search_path":"/my-blog/local-search.xml"};

    if (CONFIG.web_analytics.follow_dnt) {
      var dntVal = navigator.doNotTrack || window.doNotTrack || navigator.msDoNotTrack;
      Fluid.ctx.dnt = dntVal && (dntVal.startsWith('1') || dntVal.startsWith('yes') || dntVal.startsWith('on'));
    }
  </script>
  <script  src="/my-blog/js/utils.js" ></script>
  <script  src="/my-blog/js/color-schema.js" ></script>
  


  
<meta name="generator" content="Hexo 6.2.0"></head>


<body>
  

  <header>
    

<div class="header-inner" style="height: 70vh;">
  <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand" href="/my-blog/">
      <strong>木舟</strong>
    </a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/my-blog/">
                <i class="iconfont icon-home-fill"></i>
                首页
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/my-blog/archives/">
                <i class="iconfont icon-archive-fill"></i>
                归档
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/my-blog/categories/">
                <i class="iconfont icon-category-fill"></i>
                分类
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/my-blog/tags/">
                <i class="iconfont icon-tags-fill"></i>
                标签
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/my-blog/about/">
                <i class="iconfont icon-user-fill"></i>
                关于
              </a>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" target="_self" href="javascript:;" data-toggle="modal" data-target="#modalSearch" aria-label="Search">
              &nbsp;<i class="iconfont icon-search"></i>&nbsp;
            </a>
          </li>
          
        
        
          <li class="nav-item" id="color-toggle-btn">
            <a class="nav-link" target="_self" href="javascript:;" aria-label="Color Toggle">&nbsp;<i
                class="iconfont icon-dark" id="color-toggle-icon"></i>&nbsp;</a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

  

<div id="banner" class="banner" parallax=true
     style="background: url('/my-blog/img/default.png') no-repeat center center; background-size: cover;">
  <div class="full-bg-img">
    <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
      <div class="banner-text text-center fade-in-up">
        <div class="h2">
          
            <span id="subtitle" data-typed-text="Django-ORM操作进阶"></span>
          
        </div>

        
          
  <div class="mt-3">
    
      <span class="post-meta mr-2">
        <i class="iconfont icon-author" aria-hidden="true"></i>
        木舟
      </span>
    
    
      <span class="post-meta">
        <i class="iconfont icon-date-fill" aria-hidden="true"></i>
        <time datetime="2022-12-12 15:08" pubdate>
          2022年12月12日 下午
        </time>
      </span>
    
  </div>

  <div class="mt-1">
    
      <span class="post-meta mr-2">
        <i class="iconfont icon-chart"></i>
        
          6.2k 字
        
      </span>
    

    

    
    
      
        <span id="busuanzi_container_page_pv" style="display: none">
          <i class="iconfont icon-eye" aria-hidden="true"></i>
          <span id="busuanzi_value_page_pv"></span> 次
        </span>
        
      
    
  </div>


        
      </div>

      
    </div>
  </div>
</div>

</div>

  </header>

  <main>
    
      

<div class="container-fluid nopadding-x">
  <div class="row nomargin-x">
    <div class="side-col d-none d-lg-block col-lg-2">
      
  <aside class="sidebar" style="padding-left: 2rem; margin-right: -1rem">
    <div id="toc">
  <p class="toc-header"><i class="iconfont icon-list"></i>&nbsp;目录</p>
  <div class="toc-body" id="toc-body"></div>
</div>



  </aside>


    </div>

    <div class="col-lg-8 nopadding-x-md">
      <div class="container nopadding-x-md" id="board-ctn">
        <div id="board">
          <article class="post-content mx-auto">
            <!-- SEO header -->
            <h1 style="display: none">Django-ORM操作进阶</h1>
            
              <p class="note note-info">
                
                  
                    本文最后更新于：2023年5月23日 晚上
                  
                
              </p>
            
            
              <div class="markdown-body">
                
                <h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>ORM实际上是django对数据库的各种操作进行封装后的api, 通过调用对应的api, 就能够生成对应的sql.</p>
<p>我们在 <strong>Django起步</strong> 中学习到了简单的ORM操作, 但是我们知道, sql的使用十分复杂.</p>
<p>所以即使进ORM进行了一定的封装, 变得更加简洁易用, 但面对一些复杂的sql, 仍然需要学习其他的api.</p>
<h1 id="基础查询"><a href="#基础查询" class="headerlink" title="基础查询"></a>基础查询</h1><h2 id="all"><a href="#all" class="headerlink" title="all"></a>all</h2><p>查询所有对象，返回queryset对象。查询集，也称查询结果集、QuerySet，表示从数据库中获取的对象集合。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs python">students = Student.objects.<span class="hljs-built_in">all</span>()  <span class="hljs-comment"># select * from student;</span><br><span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;students:&quot;</span>,students)<br></code></pre></td></tr></table></figure>

<h2 id="filter"><a href="#filter" class="headerlink" title="filter"></a>filter</h2><p>筛选条件相匹配的对象，返回queryset查询集。没有数据,则返回一个空查询集</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-comment"># 查询所有的女生</span><br>students = Student.objects.<span class="hljs-built_in">filter</span>(sex=<span class="hljs-number">0</span>) <span class="hljs-comment"># select * from student where sex = 0;</span><br><span class="hljs-built_in">print</span>(students)<br></code></pre></td></tr></table></figure>

<h2 id="get"><a href="#get" class="headerlink" title="get"></a>get</h2><p>返回与所给筛选条件相匹配的对象，返回结果有且只有一个，如果查询的结果,一个记录都没有,会报错.</p>
<p>所以我们一般对不确定的查询,都会使用<strong>filter</strong></p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs python">student = Student.objects.get(wid=<span class="hljs-number">1</span>)  <span class="hljs-comment"># select * from where wid = 1;</span><br><span class="hljs-built_in">print</span>(student)<br></code></pre></td></tr></table></figure>

<h2 id="exclude"><a href="#exclude" class="headerlink" title="exclude"></a>exclude</h2><p>方法用于查询不符合条件的数据。</p>
<p>返回的是 QuerySet 类型数据，类似于 list.</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs python">students = Student.objects.exclude(sex=<span class="hljs-number">0</span>) <span class="hljs-comment"># select * from student where sex != 0;</span><br><span class="hljs-built_in">print</span>(students)<br></code></pre></td></tr></table></figure>

<h2 id="order-by"><a href="#order-by" class="headerlink" title="order_by"></a>order_by</h2><p>用于对查询结果进行排序。</p>
<ul>
<li>参数的字段名要加引号。</li>
<li>降序为在字段前面加个负号 -。</li>
</ul>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs python">books = models.Book.objects.order_by(<span class="hljs-string">&quot;price&quot;</span>) <span class="hljs-comment"># select * from book order by price;</span><br>books = models.Book.objects.order_by(<span class="hljs-string">&quot;-price&quot;</span>) <span class="hljs-comment"># select * from book order by price desc;</span><br></code></pre></td></tr></table></figure>

<h2 id="count"><a href="#count" class="headerlink" title="count"></a>count</h2><p>用于获取查询数据的数量</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs python">books = models.Book.objects.<span class="hljs-built_in">filter</span>(price=<span class="hljs-number">200</span>)<br><span class="hljs-built_in">print</span>(books.count())<br></code></pre></td></tr></table></figure>

<h2 id="first-last"><a href="#first-last" class="headerlink" title="first/last"></a>first/last</h2><p>返回第一条/最后一条数据</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs python">books = models.Book.objects.<span class="hljs-built_in">filter</span>(price=<span class="hljs-number">200</span>)<br><span class="hljs-built_in">print</span>(books.first())<br><span class="hljs-built_in">print</span>(books.last())<br></code></pre></td></tr></table></figure>

<h2 id="exists"><a href="#exists" class="headerlink" title="exists"></a>exists</h2><p>用于判断查询的结果 QuerySet 列表里是否有数据。</p>
<p>返回的数据类型是布尔，有为 True，没有为 False。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs python">books = models.Book.objects.<span class="hljs-built_in">filter</span>(price=<span class="hljs-number">200</span>)<br><span class="hljs-keyword">if</span> books.exists():<br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;books 查询结果不为空&quot;</span>)<br></code></pre></td></tr></table></figure>

<h2 id="values"><a href="#values" class="headerlink" title="values"></a>values</h2><p>用于查询部分字段的数据。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs python">books = models.Book.objects.values(<span class="hljs-string">&quot;pk&quot;</span>,<span class="hljs-string">&quot;price&quot;</span>) <span class="hljs-comment"># select pk, price from book;</span><br><span class="hljs-string">&quot;&quot;&quot;</span><br><span class="hljs-string">[</span><br><span class="hljs-string">    &#123;&quot;pk&quot;: 1, &quot;price&quot;: 100&#125;,</span><br><span class="hljs-string">    &#123;&quot;pk&quot;: 2, &quot;price&quot;: 200&#125;,</span><br><span class="hljs-string">]</span><br><span class="hljs-string">&quot;&quot;&quot;</span><br></code></pre></td></tr></table></figure>

<h1 id="逻辑查询"><a href="#逻辑查询" class="headerlink" title="逻辑查询"></a>逻辑查询</h1><p>查询字段加上 <strong>双下划线</strong>, 大多为逻辑查询.</p>
<p>比如 <code>price__in</code></p>
<h2 id="in"><a href="#in" class="headerlink" title="in"></a>in</h2><p>用于读取字段符合列表中任一元素的数据，= 号后面为列表 。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs python">books = models.Book.objects.<span class="hljs-built_in">filter</span>(price__in=[<span class="hljs-number">200</span>,<span class="hljs-number">300</span>]) <span class="hljs-comment"># 查询price等于200或300的数据 select * from book where price in (200, 300);</span><br></code></pre></td></tr></table></figure>

<h2 id="gt-gte-lt-lte"><a href="#gt-gte-lt-lte" class="headerlink" title="gt/gte/lt/lte"></a>gt/gte/lt/lte</h2><p>大于/大于等于/小于/小于等于</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs python">books = models.Book.objects.<span class="hljs-built_in">filter</span>(price__gt=<span class="hljs-number">200</span>)<br>books = models.Book.objects.<span class="hljs-built_in">filter</span>(price__gte=<span class="hljs-number">200</span>)<br>books = models.Book.objects.<span class="hljs-built_in">filter</span>(price__lt=<span class="hljs-number">200</span>)<br>books = models.Book.objects.<span class="hljs-built_in">filter</span>(price__lte=<span class="hljs-number">200</span>)<br></code></pre></td></tr></table></figure>

<h2 id="range"><a href="#range" class="headerlink" title="range"></a>range</h2><p>在 … 之间，左闭右闭区间</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs python">books=models.Book.objects.<span class="hljs-built_in">filter</span>(price__range=[<span class="hljs-number">200</span>,<span class="hljs-number">300</span>])<br></code></pre></td></tr></table></figure>

<h2 id="contains-icontains-startswith-endswith"><a href="#contains-icontains-startswith-endswith" class="headerlink" title="contains/icontains/startswith/endswith"></a>contains/icontains/startswith/endswith</h2><p>包含, 一般用作模糊查询</p>
<p><strong>icontains</strong> 为不区分大小写模糊查询<br><strong>startswith</strong> 以指定字符开头 like ‘x%’<br><strong>endswith</strong> 为指定字符结尾 like ‘%x’</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs python">books=models.Book.objects.<span class="hljs-built_in">filter</span>(title__contains=<span class="hljs-string">&quot;书&quot;</span>) <span class="hljs-comment"># select * from book where title like &#x27;%书%&#x27;;</span><br></code></pre></td></tr></table></figure>

<h1 id="操作数据"><a href="#操作数据" class="headerlink" title="操作数据"></a>操作数据</h1><blockquote>
<p>更新博客时, 操作数据的内容总是提示 “违禁内容”<br>排查了很久, 始终找不到为什么. 所以下面的内容会写的比较简单.<br>可以自行百度, 因为也并不难, 抱歉…</p>
</blockquote>
<h2 id="删除"><a href="#删除" class="headerlink" title="删除"></a>删除</h2><p><strong>delete</strong></p>
<h2 id="修改"><a href="#修改" class="headerlink" title="修改"></a>修改</h2><p>save()</p>
<p>update()</p>
<p>bulk_update()</p>
<h2 id="创建"><a href="#创建" class="headerlink" title="创建"></a>创建</h2><p>save()</p>
<p>create()</p>
<p>bulk_create()</p>
<h1 id="多表操作–外键"><a href="#多表操作–外键" class="headerlink" title="多表操作–外键"></a>多表操作–外键</h1><p>Django ORM的多表实例, 包含以下几种关联方式:</p>
<ul>
<li>一对一, 一条记录关联一条记录, 和直接在表里申明字段没什么区别</li>
<li>一对多, 一条记录关联多条件记录, 比如: 一个班级里有多名学生</li>
<li>多对多, 多条记录关联多条记录, 比如: 一本书有多个作者, 一个作者有多本书. 多对多的关系, 实际上是通过 建立中间表 然后通过 一对多 关联起来的. 所以我们着重学习一对多即可. </li>
</ul>
<p>一对一和多对多, 有兴趣的自行百度.</p>
<h2 id="创建外键关联表"><a href="#创建外键关联表" class="headerlink" title="创建外键关联表"></a>创建外键关联表</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Book</span>(models.Model):<br>    title = models.CharField(max_length=<span class="hljs-number">32</span>)<br>    price = models.DecimalField(max_digits=<span class="hljs-number">5</span>, decimal_places=<span class="hljs-number">2</span>)<br><br>    <span class="hljs-comment"># publish = models.ForeignKey(Publish, on_delete=models.CASCADE)  # 你也可以直接使用类变量</span><br>    <span class="hljs-string">&quot;&quot;&quot;</span><br><span class="hljs-string">    from xx import Xxx</span><br><span class="hljs-string">    publish = models.ForeignKey(Xxx, on_delete=models.CASCADE)  # 关联其他应用的model</span><br><span class="hljs-string">    &quot;&quot;&quot;</span><br>    <span class="hljs-string">&quot;&quot;&quot;</span><br><span class="hljs-string">    publish = models.ForeignKey(&#x27;xx.Xxx&#x27;, on_delete=models.CASCADE)  # 关联其他应用的model</span><br><span class="hljs-string">    &quot;&quot;&quot;</span><br>    publish = models.ForeignKey(<span class="hljs-string">&quot;Publish&quot;</span>, on_delete=models.CASCADE)  <span class="hljs-comment"># 外键关联</span><br><br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Publish</span>(models.Model):<br>    name = models.CharField(max_length=<span class="hljs-number">32</span>)<br></code></pre></td></tr></table></figure>

<p>创建后, book表中, 会有外键关联字段 <strong>publish_id</strong></p>
<h2 id="添加数据"><a href="#添加数据" class="headerlink" title="添加数据"></a>添加数据</h2><p>如上述表结构, 如果你想创建一条 book 记录.</p>
<p>必须要关联一个 publish.</p>
<p>所以, 如果要关联的 publish 不存在, 必须要在 book 创建前 创建publish</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs Python"><span class="hljs-comment"># publish 已存在, 直接获取</span><br>pub_obj = models.Publish.objects.<span class="hljs-built_in">filter</span>(pk=<span class="hljs-number">1</span>).first()<br>book = models.Book.objects.create(title=<span class="hljs-string">&quot;xxx&quot;</span>, price=<span class="hljs-number">200</span>, publish=pub_obj)<br></code></pre></td></tr></table></figure>

<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs Python"><span class="hljs-comment"># publish 不存在, 需要先创建</span><br>pub_obj = models.Publish.objects.create(name=<span class="hljs-string">&quot;xxx&quot;</span>).first()<br>book = models.Book.objects.create(title=<span class="hljs-string">&quot;xxx&quot;</span>, price=<span class="hljs-number">200</span>, publish=pub_obj)<br></code></pre></td></tr></table></figure>

<p>外键关联, 实际上是通过外键字段存入一个关联id.</p>
<p>所以上述操作, 实际上是给 book表中的 <strong>publish_id</strong> 赋值</p>
<p>所以我们也可以直接存入一个id</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs Python"><span class="hljs-comment"># publish 不存在, 需要先创建</span><br>pub_obj = models.Publish.objects.create(name=<span class="hljs-string">&quot;xxx&quot;</span>).first()<br><span class="hljs-comment"># book = models.Book.objects.create(title=&quot;xxx&quot;, price=200, publish=pub_obj)  # 如果存入的是数据库记录对象,那么直接指定外键字段名就好了</span><br>book = models.Book.objects.create(title=<span class="hljs-string">&quot;xxx&quot;</span>, price=<span class="hljs-number">200</span>, publish_id=pub_obj.<span class="hljs-built_in">id</span>)  <span class="hljs-comment"># 如果存入的是id, 那么需要指定 publish_id</span><br></code></pre></td></tr></table></figure>


<h2 id="外键查询"><a href="#外键查询" class="headerlink" title="外键查询"></a>外键查询</h2><p><strong>外键正向查询</strong></p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs Python">book = models.Book.objects.<span class="hljs-built_in">filter</span>(pk=<span class="hljs-number">10</span>).first()<br>res = book.publish.name<br></code></pre></td></tr></table></figure>

<p><strong>外键反向查询</strong></p>
<p>反向查询需要增加 <strong>_set</strong></p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs Python">pub = models.Publish.objects.<span class="hljs-built_in">filter</span>(name=<span class="hljs-string">&quot;xxx&quot;</span>).first()<br><span class="hljs-comment"># 当然你还可以这么写 models.Book.objects.filter(publish=pub)</span><br><span class="hljs-comment"># 当然你还可以这么写 models.Book.objects.filter(publish_id=pub_id)</span><br>res = pub.book_set.<span class="hljs-built_in">all</span>()<br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> res:<br>    <span class="hljs-built_in">print</span>(i.title)<br></code></pre></td></tr></table></figure>

<h2 id="外键跨表查询"><a href="#外键跨表查询" class="headerlink" title="外键跨表查询"></a>外键跨表查询</h2><p><strong>跨表正向查询</strong></p>
<p>属性名称__跨表的属性名称</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-comment"># 查询xxx的所有书籍的名字与价格。</span><br>res = models.Book.objects.<span class="hljs-built_in">filter</span>(publish__name=<span class="hljs-string">&quot;xxx&quot;</span>).values(<span class="hljs-string">&quot;title&quot;</span>, <span class="hljs-string">&quot;price&quot;</span>)<br></code></pre></td></tr></table></figure>

<p><strong>跨表正向查询</strong></p>
<p>小写类名__跨表的属性名称</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs python">res = models.Publish.objects.<span class="hljs-built_in">filter</span>(name=<span class="hljs-string">&quot;xxx&quot;</span>).values(<span class="hljs-string">&quot;book__title&quot;</span>,<span class="hljs-string">&quot;book__price&quot;</span>)<br></code></pre></td></tr></table></figure>


<h1 id="聚合查询"><a href="#聚合查询" class="headerlink" title="聚合查询"></a>聚合查询</h1><p>聚合查询函数是对一组值执行计算</p>
<p>使用聚合查询前要先从 django.db.models 引入 Avg、Max、Min、Count、Sum（首字母大写）。</p>
<p><code>from django.db.models import Avg,Max,Min,Count,Sum  #   引入函数</code></p>
<p>使用聚合函数查询后, 返回的对象是一个字典.</p>
<p>字典中的key默认为 <strong>属性名称加上__聚合函数名</strong></p>
<p>如果要自定义返回字典的键的名称，可以起别名：<code>aggregate(别名 = 聚合函数名(&quot;属性名称&quot;))</code></p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-comment"># 计算所有图书的平均价格</span><br>res = models.Book.objects.aggregate(Avg(<span class="hljs-string">&quot;price&quot;</span>)) <span class="hljs-comment"># &#123;price__avg: ...&#125;</span><br></code></pre></td></tr></table></figure>

<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-comment"># 计算所有图书的数量、最贵价格和最便宜价格:</span><br><span class="hljs-comment"># 起了别名&#123;c: ..., max: ..., min: ...&#125;</span><br>res=models.Book.objects.aggregate(c=Count(<span class="hljs-string">&quot;id&quot;</span>),<span class="hljs-built_in">max</span>=Max(<span class="hljs-string">&quot;price&quot;</span>),<span class="hljs-built_in">min</span>=Min(<span class="hljs-string">&quot;price&quot;</span>))<br></code></pre></td></tr></table></figure>

<h1 id="分组查询"><a href="#分组查询" class="headerlink" title="分组查询"></a>分组查询</h1><p>相当于 <strong>group by</strong></p>
<p><strong>分组查询一般会用到聚合函数，所以使用前要先从 django.db.models 引入 Avg,Max,Min,Count,Sum（首字母大写）。</strong></p>
<p><strong>在Django中, 如果想实现分组查询, 必须要通过 values + annotate</strong></p>
<p><strong>并且, values需要写在annotate前面, 这个时候, values就相当于group by</strong></p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-comment"># select count(price) as c from group by price;</span><br><span class="hljs-comment"># [&#123;c: ...&#125;, &#123;c: ...&#125;]</span><br>res = models.Book.objects.values(<span class="hljs-string">&quot;price&quot;</span>).annotate(c = Count(<span class="hljs-string">&quot;price&quot;</span>))<br></code></pre></td></tr></table></figure>

<h1 id="进阶查询"><a href="#进阶查询" class="headerlink" title="进阶查询"></a>进阶查询</h1><h2 id="F查询"><a href="#F查询" class="headerlink" title="F查询"></a>F查询</h2><p>F() 的实例可以在查询中引用字段，来比较同一个 model 实例中两个不同字段的值。</p>
<p>使用前要先从 django.db.models 引入 F: <code>from django.db.models import F</code></p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-comment"># 查询创建时间不等于更新时间的学生信息, 等于就是查询有过更新的学生信息</span><br>student_list = Student.objects.exclude(created_time=F(<span class="hljs-string">&quot;updated_time&quot;</span>))<br></code></pre></td></tr></table></figure>

<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs Python">将每一本书的价格提高<span class="hljs-number">100</span>元<br>res = models.Book.objects.update(price=F(<span class="hljs-string">&quot;price&quot;</span>)+<span class="hljs-number">100</span>)<br></code></pre></td></tr></table></figure>

<h2 id="Q查询"><a href="#Q查询" class="headerlink" title="Q查询"></a>Q查询</h2><p><strong>多个过滤器逐个调用表示逻辑与关系, 可以用来表示 或与非</strong></p>
<p>我们之前学习的 <strong>filter</strong>, 只能够表示 <strong>与</strong></p>
<p>我们之前学习的 <strong>exclude</strong>, 只能够表示 <strong>非</strong></p>
<p>想要查询 <strong>或</strong>, 就必须得借助 <strong>Q查询</strong></p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs python">Q(属性名__运算符=值)<br>Q(属性名__运算符=值) | Q(属性名__运算符=值)<br></code></pre></td></tr></table></figure>

<p>例：查询年龄小于18或者大于20的学生，使用Q对象如下。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">from</span> django.db.models <span class="hljs-keyword">import</span> Q<br>student_list = Student.objects.<span class="hljs-built_in">filter</span>( Q(age__lt=<span class="hljs-number">18</span>) | Q(age__gt=<span class="hljs-number">20</span>) )<br></code></pre></td></tr></table></figure>

<p>例：查询不小于18岁的学生，使用Q对象如下。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">from</span> django.db.models <span class="hljs-keyword">import</span> Q<br>student_list = Student.objects.<span class="hljs-built_in">filter</span>(~Q(age__lt=<span class="hljs-number">18</span>))  <span class="hljs-comment"># 查询不小于18岁的学生</span><br></code></pre></td></tr></table></figure>

<p>例：查询大于18且小于20岁的学生，使用Q对象如下。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">from</span> django.db.models <span class="hljs-keyword">import</span> Q<br>student_list = Student.objects.<span class="hljs-built_in">filter</span>( Q(age__gt=<span class="hljs-number">18</span>) &amp; Q(age__lt=<span class="hljs-number">20</span>) )<br></code></pre></td></tr></table></figure>
                
              </div>
            
            <hr/>
            <div>
              <div class="post-metas my-3">
  
    <div class="post-meta mr-3 d-flex align-items-center">
      <i class="iconfont icon-category"></i>
      

<span class="category-chains">
  
  
    
      <span class="category-chain">
        
  <a href="/my-blog/categories/%E6%B5%8B%E8%AF%95%E5%BC%80%E5%8F%91/" class="category-chain-item">测试开发</a>
  
  
    <span>></span>
    
  <a href="/my-blog/categories/%E6%B5%8B%E8%AF%95%E5%BC%80%E5%8F%91/Django/" class="category-chain-item">Django</a>
  
  

  

      </span>
    
  
</span>

    </div>
  
  
    <div class="post-meta">
      <i class="iconfont icon-tags"></i>
      
        <a href="/my-blog/tags/%E6%B5%8B%E8%AF%95%E5%BC%80%E5%8F%91/">#测试开发</a>
      
        <a href="/my-blog/tags/%E6%B5%8B%E8%AF%95%E5%B9%B3%E5%8F%B0/">#测试平台</a>
      
        <a href="/my-blog/tags/%E5%90%8E%E7%AB%AF%E6%A1%86%E6%9E%B6/">#后端框架</a>
      
    </div>
  
</div>


              
  

  <div class="license-box my-3">
    <div class="license-title">
      <div>Django-ORM操作进阶</div>
      <div>https://walker_kwu.gitee.io/my-blog/2022/12/12/notes/django/ormAction/</div>
    </div>
    <div class="license-meta">
      
        <div class="license-meta-item">
          <div>作者</div>
          <div>木舟</div>
        </div>
      
      
        <div class="license-meta-item license-meta-date">
          <div>发布于</div>
          <div>2022年12月12日</div>
        </div>
      
      
        <div class="license-meta-item license-meta-date">
          <div>更新于</div>
          <div>2023年5月23日</div>
        </div>
      
      <div class="license-meta-item">
        <div>许可协议</div>
        <div>
          
            
            
              <a target="_blank" href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
              <span class="hint--top hint--rounded" aria-label="BY - 署名">
                <i class="iconfont icon-by"></i>
              </span>
              </a>
            
              <a target="_blank" href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
              <span class="hint--top hint--rounded" aria-label="NC - 非商业性使用">
                <i class="iconfont icon-nc"></i>
              </span>
              </a>
            
              <a target="_blank" href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
              <span class="hint--top hint--rounded" aria-label="SA - 相同方式共享">
                <i class="iconfont icon-sa"></i>
              </span>
              </a>
            
          
        </div>
      </div>
    </div>
    <div class="license-icon iconfont"></div>
  </div>



              
                <div class="post-prevnext my-3">
                  <article class="post-prev col-6">
                    
                    
                      <a href="/my-blog/2022/12/14/notes/django/middleware/" title="Django中间件">
                        <i class="iconfont icon-arrowleft"></i>
                        <span class="hidden-mobile">Django中间件</span>
                        <span class="visible-mobile">上一篇</span>
                      </a>
                    
                  </article>
                  <article class="post-next col-6">
                    
                    
                      <a href="/my-blog/2022/12/11/notes/django/strat/" title="django起步">
                        <span class="hidden-mobile">django起步</span>
                        <span class="visible-mobile">下一篇</span>
                        <i class="iconfont icon-arrowright"></i>
                      </a>
                    
                  </article>
                </div>
              
            </div>

            
          </article>
        </div>
      </div>
    </div>

    <div class="side-col d-none d-lg-block col-lg-2">
      

    </div>
  </div>
</div>





  



  



  



  



  







    

    
      <a id="scroll-top-button" aria-label="TOP" href="#" role="button">
        <i class="iconfont icon-arrowup" aria-hidden="true"></i>
      </a>
    

    
      <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v" for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>

    

    
  </main>

  <footer>
    <div class="footer-inner">
  
    <div class="footer-content">
       <span>By 木舟</span> <i class="iconfont icon-love"></i> 
    </div>
  
  
    <div class="statistics">
  
  

  
    
      <span id="busuanzi_container_site_pv" style="display: none">
        总访问量 
        <span id="busuanzi_value_site_pv"></span>
         次
      </span>
    
    
      <span id="busuanzi_container_site_uv" style="display: none">
        总访客数 
        <span id="busuanzi_value_site_uv"></span>
         人
      </span>
    
    
  
</div>

  
  
  
</div>

  </footer>

  <!-- Scripts -->
  
  <script  src="https://lib.baomitu.com/nprogress/0.2.0/nprogress.min.js" ></script>
  <link  rel="stylesheet" href="https://lib.baomitu.com/nprogress/0.2.0/nprogress.min.css" />

  <script>
    NProgress.configure({"showSpinner":false,"trickleSpeed":100})
    NProgress.start()
    window.addEventListener('load', function() {
      NProgress.done();
    })
  </script>


<script  src="https://lib.baomitu.com/jquery/3.6.0/jquery.min.js" ></script>
<script  src="https://lib.baomitu.com/twitter-bootstrap/4.6.1/js/bootstrap.min.js" ></script>
<script  src="/my-blog/js/events.js" ></script>
<script  src="/my-blog/js/plugins.js" ></script>


  <script  src="https://lib.baomitu.com/typed.js/2.0.12/typed.min.js" ></script>
  <script>
    (function (window, document) {
      var typing = Fluid.plugins.typing;
      var subtitle = document.getElementById('subtitle');
      if (!subtitle || !typing) {
        return;
      }
      var text = subtitle.getAttribute('data-typed-text');
      
        typing(text);
      
    })(window, document);
  </script>




  
    <script  src="/my-blog/js/img-lazyload.js" ></script>
  




  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/tocbot/4.18.2/tocbot.min.js', function() {
    var toc = jQuery('#toc');
    if (toc.length === 0 || !window.tocbot) { return; }
    var boardCtn = jQuery('#board-ctn');
    var boardTop = boardCtn.offset().top;

    window.tocbot.init({
      tocSelector     : '#toc-body',
      contentSelector : '.markdown-body',
      headingSelector : CONFIG.toc.headingSelector || 'h1,h2,h3,h4,h5,h6',
      linkClass       : 'tocbot-link',
      activeLinkClass : 'tocbot-active-link',
      listClass       : 'tocbot-list',
      isCollapsedClass: 'tocbot-is-collapsed',
      collapsibleClass: 'tocbot-is-collapsible',
      collapseDepth   : CONFIG.toc.collapseDepth || 0,
      scrollSmooth    : true,
      headingsOffset  : -boardTop
    });
    if (toc.find('.toc-list-item').length > 0) {
      toc.css('visibility', 'visible');
    }
  });
</script>


  <script src=https://lib.baomitu.com/clipboard.js/2.0.10/clipboard.min.js></script>

  <script>Fluid.plugins.codeWidget();</script>


  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/anchor-js/4.3.1/anchor.min.js', function() {
    window.anchors.options = {
      placement: CONFIG.anchorjs.placement,
      visible  : CONFIG.anchorjs.visible
    };
    if (CONFIG.anchorjs.icon) {
      window.anchors.options.icon = CONFIG.anchorjs.icon;
    }
    var el = (CONFIG.anchorjs.element || 'h1,h2,h3,h4,h5,h6').split(',');
    var res = [];
    for (var item of el) {
      res.push('.markdown-body > ' + item.trim());
    }
    if (CONFIG.anchorjs.placement === 'left') {
      window.anchors.options.class = 'anchorjs-link-left';
    }
    window.anchors.add(res.join(', '));
  });
</script>


  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.js', function() {
    Fluid.plugins.fancyBox();
  });
</script>


  <script>Fluid.plugins.imageCaption();</script>

  <script  src="/my-blog/js/local-search.js" ></script>

  <script defer src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js" ></script>





<!-- 主题的启动项，将它保持在最底部 -->
<!-- the boot of the theme, keep it at the bottom -->
<script  src="/my-blog/js/boot.js" ></script>


  

  <noscript>
    <div class="noscript-warning">博客在允许 JavaScript 运行的环境下浏览效果更佳</div>
  </noscript>
</body>
</html>
